package com.lechuang.gateway.properties;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * route路由配置类
 * @author wangxw
 */
@Slf4j
@Data
@Component
@Configuration
@ConfigurationProperties("spring.cloud.gateway")
public class RouterProperties {

    private List<RouteDefinition> routes = new ArrayList<>();

    /**
     * <p>
     *     根据请求path，获取对应的routeId
     * </p>
     * @author liaoningbo
     * @since 2024/1/8
     */
    public String getIdByRequestPath(String requestPath){
        //获取到网关路由配置中，所有的path和对应的routeId，key是path，value是routeId
        Map<String, String> predicatesPathIdMap = this.getPathIdMap();
        Set<String> pathSet = predicatesPathIdMap.keySet();
        //通过请求path，匹配路由中配置的path
        String predicatesPath = this.matchPredicatesPath(pathSet, requestPath);
        //如果找不到，返回空
        if (StringUtils.isEmpty(predicatesPath)){
            return "";
        }
        //根据path，查到对应的routeId
        String id = predicatesPathIdMap.get(predicatesPath);
        return id == null ? "" : id;
    }


    /**
     * <p>
     *     获取到网关路由配置中，所有的path和对应的routeId，key是path，value是routeId
     * </p>
     * @author liaoningbo
     * @since 2024/1/8
     */
    public Map<String, String> getPathIdMap(){
        Map<String, String> map = new HashMap<>();
        for (RouteDefinition route : this.routes) {
            List<PredicateDefinition> predicates = route.getPredicates();
            for (PredicateDefinition predicate : predicates) {
                if ("Path".equals(predicate.getName())){
                    for (String value : predicate.getArgs().values()) {
                        if (!map.containsKey(value)){
                            map.put(value, route.getId());
                        }
                    }
                }
            }
        }
        return map;
    }

    /**
     * <p>
     *     通过请求path，匹配路由中配置的path
     * </p>
     * @author liaoningbo
     * @since 2024/1/8
     */
    private String matchPredicatesPath(Set<String> pathSet, String requestPath){
        String path = "";
        for (String p : pathSet) {
            if (this.matchPath(p, requestPath)){
                path = p;
                break;
            }
        }
        return path;
    }

    public boolean matchPath(String pattern, String path){
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        return antPathMatcher.match(pattern, path);
    }


}
